package com.athena.crm.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.athena.common.core.page.TableColumn;
import com.athena.common.helper.LoginHelper;
import com.athena.common.utils.DateUtils;
import com.athena.common.utils.StringUtils;
import com.athena.common.core.page.TableDataInfo;
import com.athena.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.athena.crm.constant.CommonConstant;
import com.athena.crm.domain.CrmClue;
import com.athena.crm.domain.CrmClueFollrecords;
import com.athena.crm.domain.bo.TCompanyUnlockBo;
import com.athena.crm.domain.bo.TUnlockRecordBo;
import com.athena.crm.service.ICrmClueService;
import com.athena.crm.service.ICrmClueFollrecordsService;
import com.athena.crm.service.ITUnlockRecordService;
import com.athena.crm.utils.SerialNumberUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import com.athena.crm.domain.bo.TCompanyBo;
import com.athena.crm.domain.vo.TCompanyVo;
import com.athena.crm.domain.CrmCompany;
import com.athena.crm.mapper.TCompanyMapper;
import com.athena.crm.service.ITCompanyService;

import java.util.*;

/**
 * 企业信息Service业务层处理
 *
 * @author ruoyi
 * @date 2023-06-18
 */
@RequiredArgsConstructor
@Service
@Slf4j
public class TCompanyServiceImpl implements ITCompanyService {

    private final TCompanyMapper baseMapper;

    private final ITUnlockRecordService unlockRecordService;

    private final ICrmClueService iCrmClueService;

    private final ICrmClueFollrecordsService ICrmClueFollrecordsService;

    private final ElasticsearchRestTemplate esRestTemplate;

    /**
     * 查询企业信息
     */
    @Override
    public TCompanyVo queryById(String id){
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder.must(QueryBuilders.termQuery("esId", id));
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
            .withQuery(boolQueryBuilder)
            .withTrackTotalHits(true)
            .build();
        SearchHits<CrmCompany> searchHits = esRestTemplate.search(nativeSearchQuery, CrmCompany.class);
        long total = searchHits.getTotalHits();
        List<SearchHit<CrmCompany>> hitList = searchHits.getSearchHits();
        List<TCompanyVo> resList = null;
        if(CollectionUtils.isNotEmpty(hitList)){
            resList= new ArrayList<>();
            for (SearchHit<CrmCompany> hit: hitList) {
                CrmCompany crmCompany = hit.getContent();
                TCompanyVo tCompanyVo = BeanUtil.toBean(crmCompany, TCompanyVo.class);
                resList.add(tCompanyVo);
            }
        }
        return resList.get(0);
    }

    /**
     * 查询企业信息列表
     */
    @Override
    public TableDataInfo<TCompanyVo> queryPageList(TCompanyBo bo, PageQuery pageQuery) {
        Pageable pageParm = PageRequest.of((new Long(pageQuery.getPageNum()).intValue() - 1),new Long(pageQuery.getPageSize()).intValue());
        Page<TCompanyVo> result = new Page<>();
        List<TableColumn> columnVos = new ArrayList<>();
        TableColumn tableColumn = new TableColumn();
        tableColumn.setProp("linkTel");
        tableColumn.setLabel("联系电话");
        tableColumn.setWidth(20);
        tableColumn.setVisible(true);
        columnVos.add(tableColumn);
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if(StringUtils.isNotBlank(bo.getComName())){
            boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("comName",bo.getComName()));
        }
        if (StringUtils.isNotEmpty(bo.getRegTimeStr())) {
            String timeStr = bo.getRegTimeStr();
            Map<String, String> regTimeMap = DateUtils.getMapTime(timeStr);
            String startTime = regTimeMap.get("startTime");
            String endTime = regTimeMap.get("endTime");
            boolQueryBuilder.must(QueryBuilders.rangeQuery("regTime").gte(startTime).lte(endTime));
        }
        if (StringUtils.isNotEmpty(bo.getRegStatus())) {
            String[] regStatusArry = bo.getRegStatus().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("regStatus", regStatusArry));
        }
        if (StringUtils.isNotEmpty(bo.getComType())) {
            String[] comTypeArry = bo.getComType().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("comType", comTypeArry));
        }
        if (StringUtils.isNotEmpty(bo.getTelFlag())) {
            String[] telFlagArry = bo.getTelFlag().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("telFlag", telFlagArry));
        }
        if (StringUtils.isNotEmpty(bo.getIsKeyPer())) {
            String[] isKeyPerArry = bo.getIsKeyPer().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("isKeyPer", isKeyPerArry));
        }
        if (StringUtils.isNotEmpty(bo.getTaxPayer())) {
            String[] taxPayerArry = bo.getTaxPayer().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("taxPayer", taxPayerArry));
        }
        if (StringUtils.isNotEmpty(bo.getTaxLevel())) {
            String[] taxLevelArry = bo.getTaxLevel().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("taxLevel", taxLevelArry));
        }
        if (StringUtils.isNotEmpty(bo.getIsBid())) {
            String[] isBidArry = bo.getIsBid().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("isBid", isBidArry));
        }
        if (StringUtils.isNotEmpty(bo.getIsHigh())) {
            String[] isHighArry = bo.getIsHigh().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("isHigh", isHighArry));
        }
        if (StringUtils.isNotEmpty(bo.getProvince())) {
            String[] provinces = bo.getProvince().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("province", provinces));
        }
        if (StringUtils.isNotEmpty(bo.getCity())) {
            String[] citys = bo.getCity().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("city", citys));
        }
        if (StringUtils.isNotEmpty(bo.getAreas())) {
            String[] areas = bo.getAreas().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("areas", areas));
        }
        if (StringUtils.isNotEmpty(bo.getTrade())) {
            String[] trades = bo.getTrade().split(",");
            boolQueryBuilder.must(QueryBuilders.termsQuery("trade", trades));
        }
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
            .withQuery(boolQueryBuilder)
            .withPageable(pageParm)
            .withTrackTotalHits(true)
            .build();
        log.info("srb: {}", nativeSearchQuery.getQuery().toString());
        SearchHits<CrmCompany> searchHits = esRestTemplate.search(nativeSearchQuery, CrmCompany.class);
        long total = searchHits.getTotalHits();
        List<SearchHit<CrmCompany>> hitList = searchHits.getSearchHits();
        List<TCompanyVo> resList = null;
        if(CollectionUtils.isNotEmpty(hitList)){
            resList= new ArrayList<>();
            for (SearchHit<CrmCompany> hit: hitList) {
                CrmCompany crmCompany = hit.getContent();
                TCompanyVo tCompanyVo = BeanUtil.toBean(crmCompany, TCompanyVo.class);
                resList.add(tCompanyVo);
            }
        }
        result.setRecords(resList);
        result.setCurrent(pageQuery.getPageNum());
        result.setTotal(total);
        return TableDataInfo.build(result, columnVos);
    }

    /**
     * 查询企业信息列表
     */
    @Override
    public List<TCompanyVo> queryList(TCompanyBo bo) {
        LambdaQueryWrapper<CrmCompany> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<CrmCompany> buildQueryWrapper(TCompanyBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<CrmCompany> lqw = Wrappers.lambdaQuery();
        lqw.like(StringUtils.isNotBlank(bo.getComName()), CrmCompany::getComName, bo.getComName());
        lqw.like(StringUtils.isNotBlank(bo.getEnName()), CrmCompany::getEnName, bo.getEnName());
        lqw.like(StringUtils.isNotBlank(bo.getShortName()), CrmCompany::getShortName, bo.getShortName());
        lqw.eq(StringUtils.isNotBlank(bo.getLogo()), CrmCompany::getLogo, bo.getLogo());
        lqw.eq(StringUtils.isNotBlank(bo.getLinkTel()), CrmCompany::getLinkTel, bo.getLinkTel());
        lqw.eq(StringUtils.isNotBlank(bo.getRegStatus()), CrmCompany::getRegStatus, bo.getRegStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getRegFundStr()), CrmCompany::getRegFundStr, bo.getRegFundStr());
        lqw.eq(bo.getRegFund() != null, CrmCompany::getRegFund, bo.getRegFund());
        lqw.eq(StringUtils.isNotBlank(bo.getRegUser()), CrmCompany::getRegUser, bo.getRegUser());
        lqw.eq(StringUtils.isNotBlank(bo.getActPayStr()), CrmCompany::getActPayStr, bo.getActPayStr());
        lqw.eq(bo.getActPay() != null, CrmCompany::getActPay, bo.getActPay());
        lqw.eq(StringUtils.isNotBlank(bo.getTrade()), CrmCompany::getTrade, bo.getTrade());
        lqw.eq(bo.getRegTime() != null, CrmCompany::getRegTime, bo.getRegTime());
        lqw.eq(bo.getCheckTime() != null, CrmCompany::getCheckTime, bo.getCheckTime());
        lqw.eq(StringUtils.isNotBlank(bo.getTradeTime()), CrmCompany::getTradeTime, bo.getTradeTime());
        lqw.eq(StringUtils.isNotBlank(bo.getComType()), CrmCompany::getComType, bo.getComType());
        lqw.eq(StringUtils.isNotBlank(bo.getProvince()), CrmCompany::getProvince, bo.getProvince());
        lqw.eq(StringUtils.isNotBlank(bo.getCity()), CrmCompany::getCity, bo.getCity());
        lqw.eq(StringUtils.isNotBlank(bo.getAreas()), CrmCompany::getAreas, bo.getAreas());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), CrmCompany::getAddress, bo.getAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getCreditCode()), CrmCompany::getCreditCode, bo.getCreditCode());
        lqw.eq(StringUtils.isNotBlank(bo.getTaxCode()), CrmCompany::getTaxCode, bo.getTaxCode());
        lqw.eq(StringUtils.isNotBlank(bo.getRegNo()), CrmCompany::getRegNo, bo.getRegNo());
        lqw.eq(StringUtils.isNotBlank(bo.getOrgCode()), CrmCompany::getOrgCode, bo.getOrgCode());
        lqw.eq(bo.getInsured() != null, CrmCompany::getInsured, bo.getInsured());
        lqw.like(StringUtils.isNotBlank(bo.getBeforeName()), CrmCompany::getBeforeName, bo.getBeforeName());
        lqw.eq(StringUtils.isNotBlank(bo.getNewReportAd()), CrmCompany::getNewReportAd, bo.getNewReportAd());
        lqw.eq(StringUtils.isNotBlank(bo.getRegAddre()), CrmCompany::getRegAddre, bo.getRegAddre());
        lqw.eq(StringUtils.isNotBlank(bo.getWebsite()), CrmCompany::getWebsite, bo.getWebsite());
        lqw.eq(StringUtils.isNotBlank(bo.getEmail()), CrmCompany::getEmail, bo.getEmail());
        lqw.eq(StringUtils.isNotBlank(bo.getOthEmail()), CrmCompany::getOthEmail, bo.getOthEmail());
        lqw.eq(StringUtils.isNotBlank(bo.getBusRange()), CrmCompany::getBusRange, bo.getBusRange());
        lqw.eq(StringUtils.isNotBlank(bo.getIsKeyPer()), CrmCompany::getIsKeyPer, bo.getIsKeyPer());
        lqw.eq(StringUtils.isNotBlank(bo.getTaxPayer()), CrmCompany::getTaxPayer, bo.getTaxPayer());
        lqw.eq(StringUtils.isNotBlank(bo.getTaxLevel()), CrmCompany::getTaxLevel, bo.getTaxLevel());
        lqw.eq(StringUtils.isNotBlank(bo.getIsBid()), CrmCompany::getIsBid, bo.getIsBid());
        lqw.eq(StringUtils.isNotBlank(bo.getIsHigh()), CrmCompany::getIsHigh, bo.getIsHigh());
        lqw.eq(StringUtils.isNotBlank(bo.getOpenTax()), CrmCompany::getOpenTax, bo.getOpenTax());
        lqw.eq(StringUtils.isNotBlank(bo.getUsableTel()), CrmCompany::getUsableTel, bo.getUsableTel());
        lqw.eq(StringUtils.isNotBlank(bo.getNoAbleTel()), CrmCompany::getNoAbleTel, bo.getNoAbleTel());
        lqw.eq(StringUtils.isNotBlank(bo.getOthTel()), CrmCompany::getOthTel, bo.getOthTel());
        lqw.eq(bo.getIsDeleted() != null, CrmCompany::getIsDeleted, bo.getIsDeleted());
        return lqw;
    }

    /**
     * 新增企业信息
     */
    @Override
    public Boolean insertByBo(TCompanyBo bo) {
        CrmCompany add = BeanUtil.toBean(bo, CrmCompany.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setEsId(add.getEsId());
        }
        return flag;
    }

    /**
     * 修改企业信息
     */
    @Override
    public Boolean updateByBo(TCompanyBo bo) {
        CrmCompany update = BeanUtil.toBean(bo, CrmCompany.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(CrmCompany entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除企业信息
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public int unlockByBo(TCompanyUnlockBo tCompanyUnlockBo , Long userId) {
        List<TUnlockRecordBo> bos = new ArrayList<>();
        List<String> ids = tCompanyUnlockBo.getEsIds();
        for (String companyId:ids) {
            TUnlockRecordBo tUnlockRecordBo = new TUnlockRecordBo();
            tUnlockRecordBo.setUserId(userId);
            tUnlockRecordBo.setComId(companyId);
            tUnlockRecordBo.setIsDown(0);
            tUnlockRecordBo.setBatchNo(SerialNumberUtil.getUnlockSerialNumber());
            bos.add(tUnlockRecordBo);
        }
        unlockRecordService.batchInsertByBo(bos);
        log.info("ids {}", tCompanyUnlockBo.getEsIds());
        return 0;
    }

    @Override
    public void chageclue(TCompanyBo bo) {
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
        if (CollectionUtils.isNotEmpty(bo.getIds())) {
            boolQueryBuilder.must(QueryBuilders.termsQuery("esId", bo.getIds()));
        }
        if(StringUtils.isNotBlank(bo.getComName())){
            boolQueryBuilder.must(QueryBuilders.matchPhraseQuery("comName",bo.getComName()));
        }
        boolQueryBuilder.mustNot(QueryBuilders.termQuery("linkTel", "-"));
        NativeSearchQuery nativeSearchQuery = new NativeSearchQueryBuilder()
            .withQuery(boolQueryBuilder)
            .withTrackTotalHits(true)
            .build();
        SearchHits<CrmCompany> searchHits = esRestTemplate.search(nativeSearchQuery, CrmCompany.class);
        long total = searchHits.getTotalHits();
        List<SearchHit<CrmCompany>> hitList = searchHits.getSearchHits();
        List<TCompanyVo> resList = null;
        if(CollectionUtils.isNotEmpty(hitList)){
            resList= new ArrayList<>();
            for (SearchHit<CrmCompany> hit: hitList) {
                CrmCompany crmCompany = hit.getContent();
                TCompanyVo tCompanyVo = BeanUtil.toBean(crmCompany, TCompanyVo.class);
                resList.add(tCompanyVo);
            }
        }
        if (resList != null) {
            List<CrmClue> crmClues = new ArrayList<>();
            for (TCompanyVo tCompanyVo:resList) {
                if (StringUtils.isNotEmpty(tCompanyVo.getRegUser()) && StringUtils.isNotEmpty(tCompanyVo.getLinkTel())) {
                    CrmClue clue = new CrmClue();
                    clue.setName(tCompanyVo.getRegUser());
                    clue.setComName(tCompanyVo.getComName());
                    clue.setRealityFollowRecords(new Date());
                    clue.setPhone(tCompanyVo.getLinkTel());
                    clue.setFollowStatus("未处理");
                    clue.setCluesSources("搜客宝");
                    clue.setClueStatus("线索");
                    clue.setDeptId(LoginHelper.getLoginUser().getDeptId());
                    clue.setDeptName(LoginHelper.getLoginUser().getDeptName());
                    clue.setHead(LoginHelper.getUsername());
                    clue.setIsDeleted("0");
                    crmClues.add(clue);
                }
            }
            List<CrmClue> crmClueList = iCrmClueService.batchInsertByBo(crmClues);
            List<CrmClueFollrecords> customerFollrecordsList = new ArrayList<>();
            if (CollectionUtils.isNotEmpty(crmClueList)) {
                for (CrmClue crmClue:crmClueList) {
                    CrmClueFollrecords crmClueFollrecords = new CrmClueFollrecords();
                    crmClueFollrecords.setClueId(crmClue.getId() + "");
                    crmClueFollrecords.setFollowUser(LoginHelper.getLoginUser().getUsername());
                    crmClueFollrecords.setFollowContent("新增线索[" + crmClue.getName() + "]");
                    crmClueFollrecords.setFlowType(CommonConstant.FOLLOW_TYPE_OPERATE_LOG);
                    crmClueFollrecords.setIsDeleted(0L);
                    customerFollrecordsList.add(crmClueFollrecords);
                }
            }
            ICrmClueFollrecordsService.batchInsertByBo(customerFollrecordsList);
        }
    }
}
